package com.RedRiver.hospitalsystem.personal_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.format.DateParser;
import com.RedRiver.hospitalsystem.personal_service.common.Personal_serviceResultCode;
import com.RedRiver.hospitalsystem.personal_service.common.exception.ScheduleException;
import com.RedRiver.hospitalsystem.personal_service.common.util.SplitTimeIntoDate;
import com.RedRiver.hospitalsystem.personal_service.infra.mapper.*;
import com.RedRiver.hospitalsystem.personal_service.infra.model.*;
import com.RedRiver.hospitalsystem.personal_service.service.Form.DoctorSchedulesForm;
import com.RedRiver.hospitalsystem.personal_service.service.Form.PageForm;
import com.RedRiver.hospitalsystem.personal_service.service.Form.RegisterInformationForm;
import com.RedRiver.hospitalsystem.personal_service.service.info.ScheduleDoctorInfo;
import com.RedRiver.hospitalsystem.personal_service.service.info.SchedulePageInfo;
import com.RedRiver.hospitalsystem.result.Result;
import com.RedRiver.hospitalsystem.personal_service.service.Form.NewDoctorSchedulesForm;
import com.RedRiver.hospitalsystem.personal_service.service.ScheduleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.Parser;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 龙世超
 * @since 2022-04-26
 */
@Service
public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper, Schedule> implements ScheduleService {

    @Resource
    private ScheduleMapper scheduleMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private SubjectMapper subjectMapper;

    @Resource
    private DepartmentMapper departmentMapper;

    @Resource
    private DoctorMapper doctorMapper;

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 给医生创建排班,并存入redis
     * @param newDoctorSchedulesForm
     * @return
     */
    @Override
    public Result<?> increaseSchedules(NewDoctorSchedulesForm newDoctorSchedulesForm) {
        //根据id查询创建排班用户对象
        Account account = accountMapper.selectById(newDoctorSchedulesForm.getAccountId());
        System.out.println(account);
        //根据id查询排班医生对象
        Doctor doctor = doctorMapper.selectById(newDoctorSchedulesForm.getDoctorId());
        System.out.println(doctor);
        //根据id查询科室信息及对应的部门信息
        Subject subject = subjectMapper.selectById(newDoctorSchedulesForm.getSubjectId());
        System.out.println(subject);
        //根据科室来查看部门信息
        Department department = departmentMapper.selectById(subject.getDepartmentId());
        System.out.println(department);
        String x = SplitTimeIntoDate.SplitDate(newDoctorSchedulesForm.getDate());
        Integer integer = SplitTimeIntoDate.SplitDateTime(newDoctorSchedulesForm.getDate());
        if (null==account||doctor==null||subject==null||department==null)throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_ERROR);
        if (department.getDepartmentState()==0) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_STATE_CLOSE);
        //根据排班医生的所在部门查询排班是否合理
        if (doctor.getDepartmentId()!=department.getDepartmentId()) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_DOCTORISNOTDEPARTMENT);
        //根据排班日期和时间查询是否已经排班
        Schedule schedule1 = scheduleMapper.selectOne(new QueryWrapper<Schedule>().eq("schedule_date", x).
                eq("schedule_time", integer));
        if (schedule1!=null) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_TIME_EXISTED);
        //创建排班
        Schedule schedule=BeanUtil.copyProperties(newDoctorSchedulesForm,Schedule.class);
        schedule.setPeopleId(newDoctorSchedulesForm.getDoctorId());
        schedule.setSchedulrType(0);
        schedule.setScheduleDate(x);
        schedule.setScheduleTime(integer);
        int insert = scheduleMapper.insert(schedule);
        if (insert==0) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_DOCTORADD_ERROR);

        //查看redis中是否有该排班信息
        String s = (String) redisTemplate.opsForHash().get(x, integer+"");
        if (!StringUtils.isEmpty(s)) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_TIME_EXISTED);

        //如果没有排班则进行在redis中进行排班
        Map<String,String> map = new HashMap<String,String>();
        map.put(integer+"",doctor.getDoctorName());
        redisTemplate.opsForHash().putAll(x,map);
        redisTemplate.expire(x,30, TimeUnit.DAYS);
        Map<Object, Object> resultMap = redisTemplate.opsForHash().entries(x);
        return Result.getInstance().setMsg("新增成功");
    }

    /**
     * 查看所有排班
     * @param form
     * @return
     */
    @Override
    public IPage<SchedulePageInfo> findPageSchedule(PageForm form) {
        Page<Schedule> scheduleInfoPage = new Page<>();
        scheduleInfoPage = this.baseMapper.selectPage(new Page<>(form.getPage() == 0 ? 1 : form.getPage(), form.getPageSize() == 0 ? 2 : form.getPageSize()),null);
        List<Schedule> scheduleInfoList = scheduleInfoPage.getRecords();
        List<SchedulePageInfo> schedulePageInfoList = BeanUtil.copyToList(scheduleInfoList, SchedulePageInfo.class);
        Page<SchedulePageInfo> page = new Page<>();
        page.setRecords(schedulePageInfoList);
        page.setCurrent(scheduleInfoPage.getCurrent());
        page.setSize(scheduleInfoPage.getSize());
        page.setTotal(scheduleInfoPage.getTotal());
        return page;
    }

    /**
     * 修改排班的人员和总号数及科室id
     * @param doctorSchedulesForm
     * @return
     */
    @Override
    public Result<?> updateSchedule(DoctorSchedulesForm doctorSchedulesForm) {
        //查看redis中是否有该排班信息
        String s = (String) redisTemplate.opsForHash().get(SplitTimeIntoDate.SplitDate(doctorSchedulesForm.getDate()),
                SplitTimeIntoDate.SplitDateTime(doctorSchedulesForm.getDate()) + "");
        System.out.println(s);
        if (StringUtils.isEmpty(s)) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_NOT_EXISTED);

        Doctor doctor = doctorMapper.selectById(doctorSchedulesForm.getPeopleId());

        //如果修改排班则进行在redis中进行排班
        Map<String,String> map = new HashMap<String,String>();
        map.put(SplitTimeIntoDate.SplitDateTime(doctorSchedulesForm.getDate())+"",doctor.getDoctorName());
        redisTemplate.opsForHash().putAll(SplitTimeIntoDate.SplitDate(doctorSchedulesForm.getDate()),map);

        Map<Object, Object> resultMap = redisTemplate.opsForHash().entries(SplitTimeIntoDate.SplitDate(doctorSchedulesForm.getDate()));
        Schedule schedule = scheduleMapper.selectById(doctorSchedulesForm.getScheduleId());
        if (schedule==null) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_NOT_EXISTED);
        schedule.setScheduleNumber(doctorSchedulesForm.getScheduleNumber());
        schedule.setPeopleId(doctorSchedulesForm.getPeopleId());
        schedule.setSubjectId(doctorSchedulesForm.getSubjectId());
        if (doctorMapper.selectById(schedule.getPeopleId()).getDepartmentId()!=subjectMapper.selectById(schedule.getSubjectId()).getDepartmentId())
                                                                    throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_DOCTORISNOTDEPARTMENT);
        int schedule_id = scheduleMapper.update(schedule, new QueryWrapper<Schedule>().eq("schedule_id", schedule.getScheduleId()));
        if (schedule_id==0) throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_UPDATE_NOT);

        return Result.getInstance().setMsg("排班更新成功");
    }

    /**
     *根据排班id删除排班
     * @param schedulesId
     * @return
     */
    @Override
    public Result<?> deleteSchedule(Integer schedulesId) {
        Schedule schedule = scheduleMapper.selectById(schedulesId);
        if (schedule==null)throw new ScheduleException(Personal_serviceResultCode.SCHEDULE_NOT_EXISTED);
        int i = scheduleMapper.deleteById(schedulesId);
        if (i==0)throw new  ScheduleException(Personal_serviceResultCode.SCHEDULE_DELETE_ERROR);
        return Result.getInstance().setMsg("删除成功");
    }

    /**
     * 根据时间查询医生是否接受挂号
     * @param registerInformationForm
     * @return
     */
    @Override
    public Result<Integer> registerInformationByDoctorId(RegisterInformationForm registerInformationForm) {
        List<Schedule> people_id = scheduleMapper.selectList(new QueryWrapper<Schedule>().eq("people_id", registerInformationForm.getDoctorId()));
        if (people_id==null) throw new ScheduleException(Personal_serviceResultCode.DOCTOR_NOT_EXISTED);
        Integer n = SplitTimeIntoDate.SplitDateTime(registerInformationForm.getDate());
        String s1 = SplitTimeIntoDate.SplitDate(registerInformationForm.getDate());
        for (Schedule schedule : people_id) {
            if (schedule.getScheduleTime()==n && schedule.getScheduleDate().equals(s1)) {
                int number = schedule.getScheduleNumber() - 1;
                schedule.setScheduleNumber(number);
                DoctorSchedulesForm doctorSchedulesForm = BeanUtil.copyProperties(schedule, DoctorSchedulesForm.class);
                doctorSchedulesForm.setDate(registerInformationForm.getDate());
                this.updateSchedule(doctorSchedulesForm);
                return Result.getInstance(Integer.class).setMsg("挂号成功").setData(number);
            }
        }
        return Result.getInstance(Integer.class).setMsg("挂号失败，该医生这段时间不接受挂号").setCode(500);
    }

    /**
     * 根据时间查询是否取消挂号
     * @param registerInformationForm
     * @return
     */
    @Override
    public Result<Integer> cancelRegisterInformationByDoctorId(RegisterInformationForm registerInformationForm) {
        List<Schedule> people_id = scheduleMapper.selectList(new QueryWrapper<Schedule>().eq("people_id", registerInformationForm.getDoctorId()));
        if (people_id==null) throw new ScheduleException(Personal_serviceResultCode.DOCTOR_NOT_EXISTED);
        Integer n = SplitTimeIntoDate.SplitDateTime(registerInformationForm.getDate());
        String s1 = SplitTimeIntoDate.SplitDate(registerInformationForm.getDate());
        for (Schedule schedule : people_id) {
            if (schedule.getScheduleTime()==n && schedule.getScheduleDate().equals(s1)) {
                int number = schedule.getScheduleNumber() + 1;
                schedule.setScheduleNumber(number);
                DoctorSchedulesForm doctorSchedulesForm = BeanUtil.copyProperties(schedule, DoctorSchedulesForm.class);
                System.out.println(doctorSchedulesForm);
                doctorSchedulesForm.setDate(registerInformationForm.getDate());
                this.updateSchedule(doctorSchedulesForm);
                return Result.getInstance(Integer.class).setMsg("取消挂号成功").setData(number);
            }
        }
        return Result.getInstance(Integer.class).setMsg("取消挂号失败").setData(null);
    }


    /**
     * 根据医生id，查看排班的科室名及其部门名字
     * @param id
     * @return
     */
    @Override
    public Result<List<ScheduleDoctorInfo>> findDoctor(Integer id) {
        List<Schedule> people_id = scheduleMapper.selectList(new QueryWrapper<Schedule>().eq("people_id", id));
        if (people_id==null) throw new ScheduleException(Personal_serviceResultCode.DOCTOR_NOT_EXISTED);
        List<ScheduleDoctorInfo> lists = new ArrayList<ScheduleDoctorInfo>();
        ScheduleDoctorInfo scheduleDoctorInfo = new ScheduleDoctorInfo();
        for (Schedule schedule : people_id) {
            scheduleDoctorInfo.setDoctorId(schedule.getPeopleId());
            scheduleDoctorInfo.setSubjectName(subjectMapper.selectById(schedule.getSubjectId()).getSubjectName());
            scheduleDoctorInfo.setScheduleDate(schedule.getScheduleDate());
            scheduleDoctorInfo.setScheduleTime(schedule.getScheduleTime());
            lists.add(scheduleDoctorInfo);
        }
        return Result.getInstanceList(ScheduleDoctorInfo.class).setData(lists);
    }

}
